package com.jrx.anytxn.param.transaction.job.billCompare.step;

import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.TlBillTransCompareDetail;
import com.jrx.anytxn.param.entity.TlThirdBillDetail;
import com.jrx.anytxn.param.mapper.ext.ExtTlThirdBillDetailMapper;
import com.jrx.anytxn.param.transaction.config.BillCompareConfig;
import com.jrx.anytxn.param.transaction.job.billCompare.bean.ThirdBillDetilReadBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.entity.TlRefundLog;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlRefundLogMapper;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 根据微信还款对账任务编排，该Processor主要处理业务日期当天未对过账的三方记录
 * 如果三方交易类型为消费（即微信还款），未对过账表示对账不平；若交易类型为退货，则尝试获取tl_refund_log记录，根据存在性和状态来进一步判断。
 */
@StepScope
@Service
public class WexinRefundLogProcessor implements ItemProcessor<TlRefundLog, ThirdBillDetilReadBean> {

    @Resource
    private ExtTlThirdBillDetailMapper extTlBillThirdDetailMapper;

    @Resource
    private ExtTlRefundLogMapper extTlRefundLogMapper;

    @Autowired
    private ISegmentService iSegmentService;

    @Autowired
    private BillCompareConfig billCompareConfig;

    @Value("#{jobExecutionContext['PR_ORG_TODAY']}")
    private Date today;

    /**
     * 参考WeixinPaymentLogProcessor逻辑处理
     * @param item
     * @return
     * @throws Exception
     */
    @Override
    public ThirdBillDetilReadBean process(TlRefundLog item) throws Exception {
        List<TlThirdBillDetail> detailList = new ArrayList<>();
        List<TlBillTransCompareDetail> compareList = new ArrayList<>();

        TlThirdBillDetail detail = null;

        // 对账一致性标记
        boolean flag = true;
        List<String> tips = new ArrayList<>(6);

        if (StringUtils.isEmpty(item.getPayId())) {
            flag = false;
            tips.add("流水号缺失");
        } else {
            detail = extTlBillThirdDetailMapper.selectByThirdSeq(item.getPayId(), item.getTenantId(), billCompareConfig.getThirdChannel());
        }

        if (ObjectUtils.nullSafeEquals(today, item.getBusinessDate())) {
            if (detail == null) {
                if (expectStatus(item, false)) {
                    flag = true;
                } else {
                    flag = false;
                    tips.add("记录缺失N-Y");
                }
            }
        }

        if (Objects.nonNull(detail)) {
            if (item.getAmount().compareTo(detail.getTransactionAmount()) != 0) {
                flag = false;
                tips.add("金额");
            }

            if (expectStatus(detail, true)) {
                if (!expectStatus(item, true)) {
                    flag = false;
                    tips.add("状态S-F");
                }
            } else {
                if (expectStatus(item, false)) {
                    flag = false;
                    tips.add("状态F-S");
                }
            }

            if (!Constant.COMPARE_FLAG_1.equals(detail.getCompareFlag())) {
                // 重新实例化避免mapper更新冗余的字段
                TlThirdBillDetail update = new TlThirdBillDetail();
                update.setId(detail.getId());
                update.setCompareFlag(Constant.COMPARE_FLAG_1);
                update.setDataFrom(billCompareConfig.getDataFrom());

                detailList.add(update);
            }
        }

        if (!flag) {
            TlBillTransCompareDetail compareDetail = new TlBillTransCompareDetail();
            compareDetail.setId(iSegmentService.getId(Constant.TL_BILL_TRANS_COMPARE_DETAIL_TABLE));
            compareDetail.setTenantId(item.getTenantId());
            compareDetail.setOrganizationId(item.getOrganizationId());
            compareDetail.setCustomerId(item.getCustomerId());
            compareDetail.setSeqNo(item.getPayId());
            compareDetail.setDataFrom(billCompareConfig.getDataFrom());

            /**
             * 对账业务日期
             */
            compareDetail.setBusinessDate(today);
            compareDetail.setThirdChannel(item.getThirdChannel());

            // TlPaymentLog存在还款或退货情况；TlRefundLog只存在退货情况
            compareDetail.setBillType(Constant.TRANSACTION_TYPE_WX_TH);

            compareDetail.setCompareStatus(Constant.COMPARE_FLAG_1);
            compareDetail.setCompareDesc(StringUtils.collectionToCommaDelimitedString(tips) + ".对账不平(三方-系统)");

            // 金额
            compareDetail.setDetailAmount(detail == null ? BigDecimal.ZERO : detail.getTransactionAmount());
            compareDetail.setTxnPostingAmnt(item.getAmount());

            // 状态
            compareDetail.setBillTransStatus(detail == null ? "" : detail.getTransStatus());
            compareDetail.setTxnTransStatus(item.getSumStatus());

            compareList.add(compareDetail);
        }

        ThirdBillDetilReadBean readBean = new ThirdBillDetilReadBean();
        readBean.setTlBillTransDetilList(detailList);
        readBean.setTlBillTransCompareDetailList(compareList);
        return readBean;
    }

    /**
     * 校验交易状态和预期状态是否匹配
     * @param item
     * @param expectSuccess
     * @return
     */
    private boolean expectStatus(TlRefundLog item, boolean expectSuccess) {
        if (expectSuccess) {
            return TransBizConstant.PAYMENT_LOG_SUM_STATUS_S.equals(item.getSumStatus());
        } else {
            return TransBizConstant.PAYMENT_LOG_SUM_STATUS_F.equals(item.getSumStatus());
        }
    }

    /**
     * 校验交易状态和预期状态是否匹配
     * @param detail
     * @param expectSuccess
     * @return
     */
    private boolean expectStatus(TlThirdBillDetail detail, boolean expectSuccess) {
        if (expectSuccess) {
            return Constant.TRANSACTION_STS_SUCCESS.equals(detail.getTransStatus());
        } else {
            return !Constant.TRANSACTION_STS_SUCCESS.equals(detail.getTransStatus());
        }
    }

}
